﻿// Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) [INCLUDE APACHE 2.0 AS AN OPTION.]
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading;
using Microsoft.PerformancePoint;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.DesignerWorkspace;
using ppscd.Configuration;

namespace ppscd
{
    /// <summary>
    /// Importer for SharePoint BI DDWX files
    /// </summary>
    public class Importer
    {
        private Microsoft.PerformancePoint.Importer importer;

        public Importer() : this(
            PerformancePointSettings.Current.AuthoringServiceUrl,
            PerformancePointSettings.Current.SiteCollectionUrl)
        {
            this.OverwriteDataSources = true;
            this.IgnoreMissingDependencies = true;
        }

        public Importer(string scorecardServerUrl, string siteCollectionUrl)
        {
            if (String.IsNullOrEmpty(scorecardServerUrl))
            {
                throw new ArgumentNullException("scorecardServerUrl");
            }

            if (String.IsNullOrEmpty(siteCollectionUrl))
            {
                throw new ArgumentNullException("siteCollectionUrl");
            }

            // validate
            new Uri(scorecardServerUrl);
            new Uri(siteCollectionUrl);

            importer = new Microsoft.PerformancePoint.Importer();
            importer.ScorecardServerUrl = scorecardServerUrl;
            importer.SiteCollectionUrl = siteCollectionUrl;
        }

        public bool OverwriteDataSources
        {
            get
            {
                return importer.OverwriteDataSources;
            }

            set
            {
                importer.OverwriteDataSources = value;
            }
        }

        public bool IgnoreMissingDependencies
        {
            get
            {
                return importer.IgnoreMissingDependencies;
            }

            set
            {
                importer.IgnoreMissingDependencies = value;
            }
        }

        public string ScorecardServerUrl
        {
            get
            {
                return importer.ScorecardServerUrl;
            }

            set
            {
                importer.ScorecardServerUrl = value;
            }
        }

        public string SiteCollectionUrl
        {
            get
            {
                return importer.SiteCollectionUrl;
            }

            set
            {
                importer.SiteCollectionUrl = value;
            }
        }

        /// <summary>
        /// Import a ddwx file
        /// </summary>
        public Collection<FirstClassElement> Import(string workspaceFilePath, string siteCollectionPath)
        {
            if (String.IsNullOrEmpty(workspaceFilePath))
            {
                throw new ArgumentNullException("workspaceFilePath");
            }

            importer.WorkspaceFile = workspaceFilePath;
            importer.ScorecardServerUrl = ScorecardServerUrl;
            importer.SiteCollectionUrl = SiteCollectionUrl;

            // Bug in ScorecareModel... need to set timeout on our web service
            ScorecardModel.GetInstance().SetTimeoutDefault();

            AutoResetEvent wait = new AutoResetEvent(false);

            importer.OpenCompleted += delegate { wait.Set(); };

            Console.WriteLine("Opening " + workspaceFilePath);

            importer.Open();

            wait.WaitOne();

            importer.ImportCompleted += delegate { wait.Set(); };

            // Re-map the importer locations to point to the data sources and content list paths
            foreach (var location in importer.Locations)
            {
                // SiteUrl = /bi
                // ListUrl = /bi/Data Connections for PerformancePoint
                //var listUrl = ;

                var destinationListUrl = Replacement.ReplaceFirst(location.Source.Location.ListUrl, PerformancePointSettings.Current.Locations);

                Console.WriteLine("Found existing location " + location.Source.Location.ListUrl);

                //Replacement.R<ListLocation>(location.Source.Location, r => r.ListUrl, PerformancePointSettings.Current.Locations);

                location.Destination = new RepositoryList();
                location.Destination.Location = new ListLocation(null, destinationListUrl);

                Console.WriteLine("Updated location to " + location.Source.Location.ListUrl);

                //location.Destination.Location.ListUrl = destinationLocationUrl;

                //new ListLocation(

                //if (location.Destination == null)
                //{
                //    location.Destination = new RepositoryList();

                //    if ((location.Source.SupportedTypes & FCOContentType.PpsDataSource) != 0)
                //    {
                //        location.Destination.Location = new ListLocation(siteCollectionPath, dataSourcesPath);
                //    }

                //    if ((location.Source.SupportedTypes & FCOContentType.PpsDashboard) != 0)
                //    {
                //        location.Destination.Location = new ListLocation(siteCollectionPath, contentListPath);
                //    }
                //}
            }

            Console.WriteLine("Deploying content to " + PerformancePointSettings.Current.DestinationServer);

            importer.Import();

            wait.WaitOne();

            // Make sure we bubble up the exceptions
            foreach (var action in importer.Results.Actions)
            {
                if (ImportActionType.Error.Equals(action.Action))
                {
                    throw action.Data["Exception"] as Exception;
                }
            }

            Console.WriteLine("Deployed " + importer.Results.ImportedElements.Count + " elements");

            return importer.Results.ImportedElements;
        }
    }
}